package com.fastjrun.security.authentication.wechat;

import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;

/**
 * 微信扫码处理提供者
 */
public class WechatAuthenticationProvider implements AuthenticationProvider {

    private UserDetailsService userDetailsService;

    public void setUserDetailsService(UserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }

    /**
     * 认证处理:
     * 1. 通过openid 查询用户信息( UserDetailsService实现)
     * 2. 当查询到用户信息, 则认为认证通过,封装Authentication对象
     *
     * @param authentication
     * @return
     * @throws AuthenticationException
     */
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        WechatAuthenticationToken wechatAuthenticationToken =
                (WechatAuthenticationToken) authentication;
        // 获取openid
        String openid = (String) wechatAuthenticationToken.getPrincipal();
        // 通过 手机号码 查询用户信息( UserDetailsService实现)
        UserDetails userDetails =
                userDetailsService.loadUserByUsername(openid);

        // 未查询到用户信息
        if (userDetails == null) {
            throw new AuthenticationServiceException("该微信未绑定");
        }

        // 认证通过
        // 封装到 MobileAuthenticationToken
        WechatAuthenticationToken authenticationToken =
                new WechatAuthenticationToken(userDetails, userDetails.getAuthorities());
        authenticationToken.setDetails(wechatAuthenticationToken.getDetails());
        //最终返回认证信息
        return authenticationToken;
    }

    /**
     * 通过这个方法,来选择对应的Provider, 即选择MobileAuthenticationProivder
     *
     * @param authentication
     * @return
     */
    @Override
    public boolean supports(Class<?> authentication) {
        return WechatAuthenticationToken.class.isAssignableFrom(authentication);
    }
}
